#ifndef __GLF_TASK_TASKMANAGER_H_INCLUDED__
#define __GLF_TASK_TASKMANAGER_H_INCLUDED__

#include <glf/concurrent/queue.h>
#include <glf/core/spinLock.h>
#include <glf/core/atomic.h>
#include <glf/mem/ephemeralAllocator.h>
#include <list>

namespace glf {

class Task;
class TaskCondition;

class TaskManager
{
public:
	~TaskManager();

	void Push(Task* task, bool signal);

	Task* Pop();

	void Signal();
	void Broadcast();

	void AddTaskCondition(TaskCondition* tc);
	void RemoveTaskCondition(TaskCondition* tc);

	bool HasPendingTask();

	int PendingTaskCount();

	void StartWork();

	void EndWork();

	bool IsWorking();

	void ForceImmediateTaskExecution(bool executeImmediately);

	bool AreTasksExecutedImmediately();

	void PauseTasksConsumption();
	
	void ResumeTasksConsumption();

	template<typename Tag>
	static TaskManager& GetInstance();

private:
	TaskManager();

	ConcurrentQueue<Task*, EphemeralAllocator<char> > m_ConcurrentTasksQueue;
	
	typedef std::list<TaskCondition*> TaskConditionList;
	TaskConditionList m_TaskConditionList;
	SpinLock m_SpinMutex;

	int m_WorkStatus;
	bool m_ExecuteImmediately;
	bool m_TasksPause;
};

} // end namespace glf

#include <glf/task/taskManager_impl.h>

#endif // __GLF_TASK_TASKMANAGER_H_INCLUDED__
